/*     */ package com.zimbra.cs.util;
/*     */ 
/*     */ import com.zimbra.common.stats.RealtimeStatsCallback;
/*     */ import com.zimbra.cs.stats.ZimbraPerf;
/*     */ import java.lang.management.GarbageCollectorMXBean;
/*     */ import java.lang.management.ManagementFactory;
/*     */ import java.lang.management.MemoryPoolMXBean;
/*     */ import java.lang.management.MemoryType;
/*     */ import java.lang.management.MemoryUsage;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Formatter;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class MemoryStats
/*     */   implements RealtimeStatsCallback
/*     */ {
/*     */   private static final String MEMPOOL_PREFIX = "mpool_";
/*     */   private static final String USED_SUFFIX = "_used";
/*     */   private static final String FREE_SUFFIX = "_free";
/*     */   private static final String GC_PREFIX = "gc_";
/*     */   private static final String COUNT_SUFFIX = "_count";
/*     */   private static final String TIME_SUFFIX = "_ms";
/*     */   private static final String MINOR = "minor";
/*     */   private static final String MAJOR = "major";
/*     */   private static final String HEAP_USED = "heap_used";
/*     */   private static final String HEAP_FREE = "heap_free";
/*     */   private static final String GC_MINOR_COUNT = "gc_minor_count";
/*     */   private static final String GC_MINOR_TIME = "gc_minor_ms";
/*     */   private static final String GC_MAJOR_COUNT = "gc_major_count";
/*     */   private static final String GC_MAJOR_TIME = "gc_major_ms";
/*     */   private static final String MEMMGR_GC_MAJOR_MSC = "MarkSweepCompact";
/*     */   private static final String MEMMGR_GC_MAJOR_CMS = "ConcurrentMarkSweep";
/*     */   private static final String MEMMGR_GC_MAJOR_PS_MARKSWEEP = "PS MarkSweep";
/*     */   private static final String MEMMGR_GC_MAJOR_TRAIN = "Train";
/*     */   private static Set<String> sMajorCollectors;
/*  71 */   private static MemoryStats sInstance = null;
/*     */   
/*     */   static
/*     */   {
/*  75 */     sMajorCollectors = new HashSet(4);
/*  76 */     sMajorCollectors.add("MarkSweepCompact");
/*  77 */     sMajorCollectors.add("ConcurrentMarkSweep");
/*  78 */     sMajorCollectors.add("PS MarkSweep");
/*  79 */     sMajorCollectors.add("Train");
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static String dumpGarbageCollectors()
/*     */   {
/*  88 */     StringBuilder sb = new StringBuilder();
/*     */     
/*  90 */     List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
/*  91 */     for (GarbageCollectorMXBean gc : gcs) {
/*  92 */       long timePerGc = 0L;
/*  93 */       if (gc.getCollectionCount() > 0L) {
/*  94 */         timePerGc = gc.getCollectionTime() / gc.getCollectionCount();
/*     */       }
/*  96 */       sb.append(new Formatter().format("GC: %s(%s)  count=%d  time=%d(%,dms per collection)\n", new Object[] { gc.getName(), gc.isValid() ? "VALID" : "INVALID", Long.valueOf(gc.getCollectionCount()), Long.valueOf(gc.getCollectionTime()), Long.valueOf(timePerGc) }));
/*     */       
/*  98 */       sb.append(new Formatter().format("\tPools: \"", new Object[0]));
/*  99 */       for (String s : gc.getMemoryPoolNames()) {
/* 100 */         sb.append(s).append(", ");
/*     */       }
/* 102 */       sb.append("\"\n");
/*     */     }
/* 104 */     return sb.toString();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static String dumpMemoryPools()
/*     */   {
/* 113 */     StringBuilder sb = new StringBuilder();
/*     */     
/* 115 */     long totalUsed = 0L;
/* 116 */     long totalReserved = 0L;
/* 117 */     long totalMax = 0L;
/* 118 */     long collectUsed = 0L;
/*     */     
/* 120 */     List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
/* 121 */     for (MemoryPoolMXBean pool : pools) {
/* 122 */       MemoryUsage usage = pool.getUsage();
/* 123 */       if (pool.getType() == MemoryType.HEAP)
/*     */       {
/*     */ 
/* 126 */         sb.append(new Formatter().format("\t\"%s\" memory used: %,d  reserved: %,d  max: %,d", new Object[] { pool.getName(), Long.valueOf(usage.getUsed()), Long.valueOf(usage.getCommitted()), Long.valueOf(usage.getMax()) }));
/*     */         
/*     */ 
/* 129 */         totalUsed += usage.getUsed();
/* 130 */         totalReserved += usage.getCommitted();
/* 131 */         totalMax += usage.getMax();
/*     */         
/* 133 */         MemoryUsage collect = pool.getCollectionUsage();
/* 134 */         if (collect != null) {
/* 135 */           sb.append(new Formatter().format(" collectUsed: %,d", new Object[] { Long.valueOf(collect.getUsed()) }));
/* 136 */           if (collect.getUsed() > 0L) {
/* 137 */             collectUsed += collect.getUsed();
/*     */           } else {
/* 139 */             collectUsed += usage.getUsed();
/*     */           }
/*     */         } else {
/* 142 */           collectUsed += usage.getUsed();
/*     */         }
/* 144 */         sb.append('\n');
/*     */       } }
/* 146 */     sb.append(new Formatter().format("RuntimeTotal=%,d  RuntimeMax=%,d  RuntimeFree=%,d  TotUsed=%,d  TotReserved=%,d  TotMax=%,d  CollectUsed=%,d\n", new Object[] { Long.valueOf(Runtime.getRuntime().totalMemory()), Long.valueOf(Runtime.getRuntime().maxMemory()), Long.valueOf(Runtime.getRuntime().freeMemory()), Long.valueOf(totalUsed), Long.valueOf(totalReserved), Long.valueOf(totalMax), Long.valueOf(collectUsed) }));
/*     */     
/*     */ 
/*     */ 
/* 150 */     return sb.toString();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static String[] getGarbageCollectorNames()
/*     */   {
/* 162 */     List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
/* 163 */     String[] toRet = new String[gcs.size()];
/* 164 */     int i = 0;
/* 165 */     for (GarbageCollectorMXBean gc : gcs) {
/* 166 */       toRet[i] = gc.getName();
/* 167 */       i++;
/*     */     }
/* 169 */     return toRet;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static String[] getHeapPoolNames()
/*     */   {
/* 183 */     List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
/* 184 */     ArrayList<String> array = new ArrayList(pools.size());
/*     */     
/* 186 */     for (MemoryPoolMXBean pool : pools)
/*     */     {
/*     */ 
/*     */ 
/*     */ 
/* 191 */       array.add(pool.getName());
/*     */     }
/* 193 */     String[] toRet = new String[array.size()];
/* 194 */     return (String[])array.toArray(toRet);
/*     */   }
/*     */   
/*     */   public static void shutdown() {
/* 198 */     sInstance.doShutdown();
/* 199 */     sInstance = null;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void startup()
/*     */   {
/* 207 */     sInstance = new MemoryStats();
/*     */   }
/*     */   
/*     */   private static final String getGCCountColName(String gcName) {
/* 211 */     return "gc_" + spaceToUs(gcName) + "_count";
/*     */   }
/*     */   
/*     */   private static final String getGCTimeColName(String gcName) {
/* 215 */     return "gc_" + spaceToUs(gcName) + "_ms";
/*     */   }
/*     */   
/*     */   private static final String getPoolFreeSizeColName(String poolName) {
/* 219 */     return "mpool_" + spaceToUs(poolName) + "_free";
/*     */   }
/*     */   
/*     */   private static final String getPoolUsedSizeColName(String poolName) {
/* 223 */     return "mpool_" + spaceToUs(poolName) + "_used";
/*     */   }
/*     */   
/*     */   private static final String spaceToUs(String s) {
/* 227 */     return s.replace(' ', '_');
/*     */   }
/*     */   
/*     */   private MemoryStats() {
/* 231 */     ZimbraPerf.addStatsCallback(this);
/*     */     
/*     */ 
/* 234 */     for (String gc : getGarbageCollectorNames()) {
/* 235 */       gc = gc.toLowerCase();
/* 236 */       ZimbraPerf.addRealtimeStatName(getGCCountColName(gc), "Number of times that " + gc + " GC was invoked");
/* 237 */       ZimbraPerf.addRealtimeStatName(getGCTimeColName(gc), "Time (ms) spent on " + gc + " GC");
/*     */     }
/* 239 */     ZimbraPerf.addRealtimeStatName("gc_minor_count", "Number of times that minor GC was invoked");
/* 240 */     ZimbraPerf.addRealtimeStatName("gc_minor_ms", "Time (ms) spent on minor GC");
/* 241 */     ZimbraPerf.addRealtimeStatName("gc_major_count", "Number of times that major GC was invoked");
/* 242 */     ZimbraPerf.addRealtimeStatName("gc_major_ms", "Time (ms) spent on major GC");
/*     */     
/*     */ 
/* 245 */     for (String pool : getHeapPoolNames()) {
/* 246 */       pool = pool.toLowerCase();
/* 247 */       ZimbraPerf.addRealtimeStatName(getPoolUsedSizeColName(pool), "Number of bytes used in the " + pool + " memory pool");
/* 248 */       ZimbraPerf.addRealtimeStatName(getPoolFreeSizeColName(pool), "Number of bytes free in the " + pool + " memory pool");
/*     */     }
/*     */     
/*     */ 
/* 252 */     ZimbraPerf.addRealtimeStatName("heap_used", "Number of bytes used in the entire JVM heap");
/* 253 */     ZimbraPerf.addRealtimeStatName("heap_free", "Number of bytes free in the entire JVM heap");
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public Map<String, Object> getStatData()
/*     */   {
/* 260 */     Map<String, Object> toRet = new HashMap();
/*     */     
/*     */ 
/* 263 */     long minorCount = 0L;long minorTime = 0L;long majorCount = 0L;long majorTime = 0L;
/* 264 */     List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
/* 265 */     for (GarbageCollectorMXBean gc : gcs) {
/* 266 */       String gcName = gc.getName();
/* 267 */       long count = gc.getCollectionCount();
/* 268 */       long time = gc.getCollectionTime();
/* 269 */       String gcNameLower = gcName.toLowerCase();
/* 270 */       toRet.put(getGCCountColName(gcNameLower), Long.valueOf(count));
/* 271 */       toRet.put(getGCTimeColName(gcNameLower), Long.valueOf(time));
/* 272 */       if (sMajorCollectors.contains(gcName)) {
/* 273 */         majorCount += count;
/* 274 */         majorTime += time;
/*     */       } else {
/* 276 */         minorCount += count;
/* 277 */         minorTime += time;
/*     */       }
/*     */     }
/* 280 */     toRet.put("gc_minor_count", Long.valueOf(minorCount));
/* 281 */     toRet.put("gc_minor_ms", Long.valueOf(minorTime));
/* 282 */     toRet.put("gc_major_count", Long.valueOf(majorCount));
/* 283 */     toRet.put("gc_major_ms", Long.valueOf(majorTime));
/*     */     
/* 285 */     long heapTotal = 0L;
/* 286 */     long heapUsed = 0L;
/*     */     
/*     */ 
/* 289 */     List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
/* 290 */     for (MemoryPoolMXBean pool : pools)
/*     */     {
/*     */ 
/*     */ 
/*     */ 
/* 295 */       String poolName = pool.getName().toLowerCase();
/*     */       long committed;
/*     */       long used;
/*     */       try {
/* 299 */         MemoryUsage usage = pool.getUsage();
/* 300 */         committed = usage.getCommitted();
/* 301 */         used = usage.getUsed();
/*     */       }
/*     */       catch (IllegalArgumentException e)
/*     */       {
/*     */         long committed;
/*     */         long used;
/* 307 */         String msg = e.getMessage();
/*     */         
/* 309 */         Pattern p = Pattern.compile("committed = (\\d+) should be < max = (\\d+)");
/* 310 */         Matcher m = p.matcher(msg);
/* 311 */         if (m.find()) {
/* 312 */           committed = Long.parseLong(m.group(1));
/* 313 */           used = Long.parseLong(m.group(2));
/*     */         } else {
/* 315 */           committed = 0L;
/* 316 */           used = 0L;
/*     */         }
/*     */       }
/* 319 */       if (pool.getType() == MemoryType.HEAP) {
/* 320 */         heapTotal += committed;
/* 321 */         heapUsed += used;
/*     */       }
/* 323 */       long curpoolFree = committed - used;
/* 324 */       toRet.put(getPoolUsedSizeColName(poolName), Long.valueOf(used));
/* 325 */       toRet.put(getPoolFreeSizeColName(poolName), Long.valueOf(curpoolFree));
/*     */     }
/*     */     
/*     */ 
/* 329 */     toRet.put("heap_used", Long.valueOf(heapUsed));
/* 330 */     toRet.put("heap_free", Long.valueOf(heapTotal - heapUsed));
/*     */     
/* 332 */     return toRet;
/*     */   }
/*     */   
/*     */   private void doShutdown() {}
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/util/MemoryStats.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */